/*
 * =====================================================================================
 *
 *       Filename:  State.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2015年02月04日 18时20分13秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  LiuYi (), swliuyi@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <limits.h>
#include <iostream>
#include <tr1/memory>

using namespace std;

class Context;
class State;
class StateA;
class StateB;

class State
{
    public:
        virtual void Handle(Context *context) = 0;
        virtual string GetName() = 0;
};

class StateA: public State
{
    public:
        void Handle(Context * context);
        string GetName()
        {
            return  "StateA";
        }
};

class StateB: public State
{
    public:
        string GetName()
        {
            return  "StateB";
        }
        void Handle(Context *context);
};

class Context
{
    private:
        tr1::shared_ptr<State> m_state;
    public:
        Context(State * state):m_state(state){}
        void SetState(State * state)
        {
            m_state.reset(state);
            cout<<"now state: "<<state->GetName()<<endl;
        }
        const State * GetState() const
        {
            return m_state.get();
        }
        void Request()
        {
            m_state->Handle(this);
        }
};


void StateA::Handle(Context * context)
{
    context->SetState(new StateB());
}

void StateB::Handle(Context *context)
{
    context->SetState(new StateA());
}

int main(int argc, char *argv[])
{
    tr1::shared_ptr<Context> c (new Context(new StateA()));
    c->Request();
    c->Request();
    c->Request();
    c->Request();
    c->Request();
    c->Request();
}
